package cn.edu.nju.ws.sview.wyge.servlets;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.rdf.URIResource;
import cn.edu.nju.ws.sview.wyge.relations.adataset.CustomDataset;
import cn.edu.nju.ws.sview.wyge.relations.adataset.relations.Pattern;
import cn.edu.nju.ws.sview.wyge.relations.adataset.relations.Relation;
import cn.edu.nju.ws.sview.wyge.relations.adataset.relations.TriplePattern;
import cn.edu.nju.ws.sview.wyge.relations.adataset.relations.qxliu.relation.RelationEvaluation;
import cn.edu.nju.ws.sview.wyge.relations.datasets.DatasetItem;

/**
 * 给定relation_id以及dataset得到relation的答案
 */
public class RelationResult extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public RelationResult() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	@SuppressWarnings("unchecked")
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String json = null;
		response.setCharacterEncoding("utf-8");
		if (request.getParameter("data") != null) {
			json = request.getParameter("data");
//			System.out.println("in RelationResult:"+json);
			String str = URLDecoder.decode(json, "UTF-8");
			JSONObject regtJSON = (JSONObject) JSONValue.parse(str);
			int id = Integer.parseInt((String) regtJSON.get("id"));
			String ds_type = (String) regtJSON.get("ds_type");
			String idStr = (String) regtJSON.get("idStr");
			int ds_id = Integer.parseInt((String) regtJSON.get("ds_id"));
			String disAll = (String) regtJSON.get("dis_all");
			String isnew = (String) regtJSON.get("new");
			
			//for use_time
			boolean isTop = false;
			if(regtJSON.get("isTop") != null){
				isTop = (Boolean) regtJSON.get("isTop");
			}
			if(isTop){
				
			}
			//==============
			ArrayList<Integer> docs = new ArrayList<Integer>();
			if(ds_type.contentEquals(DatasetItem.TEMP_GENRE)){
				String[] strList = idStr.split("_");
				for(String did :strList){
					if(did.trim().length()>0){
						docs.add(Integer.parseInt(did));
					}
				}
			}else if (ds_type.equals("uri")) {
				docs.add(ds_id);
			} else if (ds_type.equals("custom")) {
				docs.addAll(CustomDataset.getURLIDsByCustomDatasetId(ds_id));
			}

			Relation rel = null;
			if (isnew != null) {
				rel = Relation.getInstance(id);
			} else {
				rel = (Relation) request.getSession().getAttribute(
						"relation" + id);
			}
			if (rel == null) {
				rel = Relation.getInstance(id);
			}

			Pattern pat = rel.getPattern();
			ArrayList<TriplePattern> triples = pat.getTriples();
			ArrayList<String[]> in = new ArrayList<String[]>();
			for (TriplePattern t : triples) {
				String[] row = new String[3];
				String s = t.getSubject();
				String p = "";
				String o = t.getObject();
				try {
					if (s.startsWith("u")) {
						int sid = Integer.parseInt(s.substring(1));
						s = "u" + URIIDCache.getInstance().getURI(sid);
					}
					p = "u" + URIIDCache.getInstance().getURI(t.getProperty());
					if (o.startsWith("u")) {
						int oid = Integer.parseInt(o.substring(1));
						o = "u" + URIIDCache.getInstance().getURI(oid);
					}
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				row[0] = s;
				row[1] = p;
				row[2] = o;
				in.add(row);
			}

			RelationEvaluation releval = new RelationEvaluation();
			ArrayList<ArrayList<String>> vals = releval.getValuesFromPatterns(in, docs);
			JSONArray elements = new JSONArray();

			ArrayList<String> tableHead = vals.get(0);
			JSONArray jsary = new JSONArray();
			for (String h : tableHead) {
				JSONObject jsob = new JSONObject();
				if (disAll == null) {
					if (!rel.getVariableRole(h).equals("")) {
						jsob.put("v", h);
						jsob.put("vname", rel.getVariableRole(h));
						jsary.add(jsob);
					}
				} else {
					jsob.put("v", h);
					jsob.put("vname", rel.getVariableRole(h));
					jsary.add(jsob);
				}
			}
			elements.add(jsary);

			for (int i = 1; i < vals.size(); i++) {
				JSONArray jsar = new JSONArray();
				ArrayList<String> row = vals.get(i);
				for (int j = 0; j < tableHead.size(); j++) {
					JSONObject jsob = new JSONObject();
					String v = tableHead.get(j);
					if (disAll == null) {
						if (!rel.getVariableRole(v).equals("")) {
							String code = row.get(j);
							String name = getName(code);
							String content = getContent(code);
							String displayName = getDisplayName(code);
							jsob.put("v", v);
							jsob.put("name", name);
							jsob.put("content", content);
							jsob.put("displayName", displayName);
							if(code.startsWith("u")){
								try {
									jsob.put("uri_id", URIIDCache.getInstance().getURIID(code.substring(1), false));
								} catch (NumberFormatException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								} catch (Throwable e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
							jsar.add(jsob);
						}
					} else {
						String code = row.get(j);
						String name = getName(code);
						String content = getContent(code);
						String displayName = getDisplayName(code);
						jsob.put("v", v);
						jsob.put("name", name);
						jsob.put("content", content);
						jsob.put("displayName", displayName);
						if(code.startsWith("u")){
							try {
								jsob.put("uri_id", URIIDCache.getInstance().getURIID(code.substring(1), false));
							} catch (NumberFormatException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							} catch (Throwable e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}
						jsar.add(jsob);
					}
				}
				elements.add(jsar);
			}
			JSONObject result = new JSONObject();
			result.put("result", elements);
			response.getWriter().print(result);
		}
	}
//	private String getDisplayName(String code){
	public static String getDisplayName(String code){
		String displayName = null;
		if(code.startsWith("u")){
			displayName = URIResource.getLabel(URIResource.getURIIdByURIString(code.substring(1)), "");
//			System.out.println("code:"+code+"|disp:"+displayName);
		}else{
			displayName=code.substring(1);
		}
		return displayName;
	}
//	private String getName(String code) {
	public static String getName(String code) {
		String name = code;
		if (code.startsWith("u")) {
			String uri = code.substring(1);
			int uid = 0;
			try {
				uid = URIIDCache.getInstance().getURIID(uri, false);
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			name = "u" + uid;
		}
		return name;
	}

//	private String getContent(String code) {
	public static String getContent(String code) {
		if (code.startsWith("u")) {
			return code.substring(1);
		}
		if (code.startsWith("l")) {
			return code.substring(1);
		}
		return code;
	}
}
